#include <stdio.h>
#include <stdlib.h>

#include <sys/time.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>

#include "best_lock.h"
#include "atomic.h"

int numThreads;
int tid_gen = 0;
pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;

int __thread tid;

int tas_pause (int delay) {

   int i, j;
   
   for (i = 0; i < delay; i ++) {
      //what do we want the base unit of waiting to be ? 1 nop ? 5 nops ?
      for (j = 0; j < TAS_TIME_UNIT; j ++) {
         asm __volatile__ ("nop");
      }
   }
   
   return 0;
}


int best_mutex_lock(int *mutex) 
{
    int result = TAS_UNLOCKED, delay = 1;
    register int countExp = delay;

    while ((result = testandset (mutex)) == TAS_LOCKED) {
       //implement backoff here; you can (should) use tas_pause()
       tas_pause(countExp);
       countExp = countExp << 1;
    }

    return 0;
}

int best_mutex_unlock(int *mutex) 
{

    *mutex = TAS_UNLOCKED;
    
    return 0;
}
